/****************************************Copyright (c)**************************************************
**        
**                                      
**                                 http://www.openmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: 			AT45DB161Drv.h
** Last modified Date: 	
** Last Version: 		1.0
** Descriptions: 		
**
**------------------------------------------------------------------------------------------------------
** Created 	 By: 		apleilx    
** Created date: 		2015-6-15  
** Version     :        1.0          
** Descriptions: 		version 1.0  
**
********************************************************************************************************/

#ifndef __F016BDRV_H 
#define __F016BDRV_H

#ifdef _AT45DB_MODULE_
#define AT45DB_EXTE
#else
#define AT45DB_EXTE extern
#endif

#include <stdint.h>
/*------------------------------------------------------------------------------------------------------*
 * AT48DB161 :                                                          describe
 * Main Memory    : 16 sector x 32 block x 8 page x 512/528B     ROM       
 *                  16 sector x 256 page x 512/528B
                    512 block x 8   page x 512/528B
					4096 page x 512/528B
 * Buffer1        : 512/528B                                     RAM
 * Buffer2        : 512/528B                                     RAM
 * Protection Reg : 16B                                          ROM     For 16 sector
 * LockDown   Reg : 16B                                          OPT     For 16 sector
 * Security   Reg : 64B + 64B                                    OPT+RO  
 * Status     Reg : 1B                                           RO      [7:RDY][6:COMP][5-4-3-2:][1:PROTECT][0:PAGE SIZE]
 * Device     ID  : 4B                                           RO 
 * Power of 2     : 1b                                           OPT
 * 
 * When the CS is low, master controler send CMD . The divice will do something after the CS is de-asserted.
 *------------------------------------------------------------------------------------------------------*/

#define AT45_PAGE_SIZE                  (512)
#define AT45_BUF_SIZE                   (512)
#define AT45_PROTECTION_REG_SIZE        (16)
#define AT45_LOCKDOWN_REG_SIZE          (16)
#define AT45_SECURITY_REG_WRITE_SIZE    (64)
#define AT45_SECURITY_REG_READ_SIZE     (128)

#define AT45_BUF_ADDR_MASK              (0x1FF)
#define AT45_BUF_ADDR_MAX               (0x1FF)
#define AT45_ADDR_MASK                  (0x1FFFFF)
#define AT45_ADDR_MAX                   (0x1FFFFF)

#define AT45_ST_PAGE_SIZE_MASK          (1)
#define AT45_ST_PROTECT_MASK            (1 << 1)
#define AT45_ST_COMP_MASK               (1 << 6)
#define AT45_ST_RDY_MASK                (1 << 7)
#define AT45_ST_BUSY_MASK               (1 << 7)

#define AT45_ST_RDY                     (1 << 7)
#define AT45_ST_BUSY                    (0)
#define AT45_ST_PAGE_SIZE_512           (1)
#define AT45_ST_PAGE_SIZE_528           (0)
#define AT45_ST_PROTECTED               (1 << 1)
#define AT45_ST_UNPROTECTED             (0)


#define AT45_MAIN_MEM_READ              ((uint8_t)0xD2)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY4-R1....Rn CS^ 
#define AT45_ARRAY_READ                 ((uint8_t)0x03)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^ 
#define AT45_ARRAY_READ_FAST            ((uint8_t)0x0B)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^ 
#define AT45_BUF1_READ                  ((uint8_t)0xD1)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used
#define AT45_BUF2_READ                  ((uint8_t)0xD3)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used
#define AT45_BUF1_READ_FAST             ((uint8_t)0xD4)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^  //Only Byte Address is used
#define AT45_BUF2_READ_FAST             ((uint8_t)0xD6)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^  //Only Byte Address is used

#define AT45_BUF1_WRITE                 ((uint8_t)0x84)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used    
#define AT45_BUF2_WRITE                 ((uint8_t)0x87)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used 
#define AT45_BUF1_TO_MAIN_INERASE       ((uint8_t)0x83)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
#define AT45_BUF2_TO_MAIN_INERASE       ((uint8_t)0x86)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
#define AT45_BUF1_TO_MAIN_NOERASE       ((uint8_t)0x88)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
#define AT45_BUF2_TO_MAIN_NOERASE       ((uint8_t)0x89)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
#define AT45_PAGE_ERASE                 ((uint8_t)0x81)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
#define AT45_BLOCK_ERASE                ((uint8_t)0x50)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only block address is used
#define AT45_SECTOR_ERASE               ((uint8_t)0x7C)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only sector address is used
#define AT45_CHIP_ERASE                 ((uint32_t)0xC794809A)      //Sequence : CS_ MB-UB-HB-LB CS^ 
#define AT45_MAIN_PROG_THROUGH_BUF1     ((uint8_t)0x82)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^
#define AT45_MAIN_PROG_THROUGH_BUF2     ((uint8_t)0x85)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^

#define AT45_ENABLE_SECTOR_PROTECTION   ((uint32_t)0x3D2A7FA9)      //Sequence : CS_ MB-UB-HB-LB CS^ 
#define AT45_DISABLE_SECTOR_PROTECTION  ((uint32_t)0x3D2A7F9A)      //Sequence : CS_ MB-UB-HB-LB CS^
#define AT45_PROTECTION_REG_ERASE       ((uint32_t)0x3D2A7FCF)      //Sequence : CS_ MB-UB-HB-LB CS^ 
#define AT45_PROTECTION_REG_PROG        ((uint32_t)0x3D2A7FFC)      //Sequence : CS_ MB-UB-HB-LB-WDn .... WDn+15 CS^ 
#define AT45_PROTECTION_REG_READ        ((uint8_t)0x32)             //Sequence : CS_ LB-DUMMY3-RDn .... RDn+15 CS^
#define AT45_LOCKDOWN_REG_PROG          ((uint32_t)0x3D2A7F30)      //Sequence : CS_ MB-UB-HB-LB-ADDUB-ADDHB-ADDLB CS^ 
#define AT45_LOCKDOWN_REG_READ          ((uint8_t)0x35)             //Sequence : CS_ LB-DUMMY3-RDn .... RDn+15 CS^
#define AT45_SECURITY_REG_PROG          ((uint32_t)0x9B000000)      //Sequence : CS_ MB-UB-HB-LB-WDn .... WDn+x CS^
#define AT45_SECURITY_REG_READ          ((uint8_t)0x77)             //Sequence : CS_ LB-DUMMY3-RDn .... RDn+x CS^
#define AT45_POWER_OF_2                 ((uint32_t)0x3D2A80A6)      //Sequence : CS_ MB-UB-HB-LB CS^ 

#define AT45_MAIN_MEM_TO_BUF1_TRANSFER  ((uint8_t)0x53)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used
#define AT45_MAIN_MEM_TO_BUF2_TRANSFER  ((uint8_t)0x55)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used
#define AT45_MAIN_MEM_TO_BUF1_COMPARE   ((uint8_t)0x60)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used             
#define AT45_MAIN_MEM_TO_BUF2_COMPARE   ((uint8_t)0x61)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used                
#define AT45_AUTO_REWRITE_THROUGH_BUF1  ((uint8_t)0x58)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used              
#define AT45_AUTO_REWRITE_THROUGH_BUF2  ((uint8_t)0x59)             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^  //Only Page Address is used             
#define AT45_DEEP_POWER_DOWN            ((uint8_t)0xB9)             //Sequence : CS_ LB CS^ 
#define AT45_DEEP_POWER_DOWN_RESUME     ((uint8_t)0xAB)             //Sequence : CS_ LB CS^ 
#define AT45_STATUS_REG_READ            ((uint8_t)0xD7)             //Sequence : CS_ LB-RD CS^
#define AT45_DEVICE_ID_READ             ((uint8_t)0x9F)             //Sequence : CS_ LB-RLB-RHB-RUB CS^ 

/*---------------------------------These cmd should be send with a address of the device-----------------------------------------*/
typedef enum
{
	CMD_BUF1_TO_MAIN_INERASE       = ((uint8_t)0x83),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
	CMD_BUF2_TO_MAIN_INERASE       = ((uint8_t)0x86),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
	CMD_BUF1_TO_MAIN_NOERASE       = ((uint8_t)0x88),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
	CMD_BUF2_TO_MAIN_NOERASE       = ((uint8_t)0x89),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
	CMD_PAGE_ERASE                 = ((uint8_t)0x81),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page address is used
	CMD_BLOCK_ERASE                = ((uint8_t)0x50),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only block address is used
	CMD_SECTOR_ERASE               = ((uint8_t)0x7C),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only sector address is used
	CMD_MAIN_MEM_TO_BUF1_TRANSFER  = ((uint8_t)0x53),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used
	CMD_MAIN_MEM_TO_BUF2_TRANSFER  = ((uint8_t)0x55),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used
	CMD_MAIN_MEM_TO_BUF1_COMPARE   = ((uint8_t)0x60),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used             
	CMD_MAIN_MEM_TO_BUF2_COMPARE   = ((uint8_t)0x61),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used                
	CMD_AUTO_REWRITE_THROUGH_BUF1  = ((uint8_t)0x58),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used              
	CMD_AUTO_REWRITE_THROUGH_BUF2  = ((uint8_t)0x59)              //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB CS^ //Only Page Address is used  
} AT45_CMD_WITH_ADDR_Type;

/*---------------------------------The divice will bu power down or resume with thess cmd-----------------------------------------*/
typedef enum
{
	CMD_POWER_DOWN                 = ((uint8_t)0xB9),             //Sequence : CS_ LB CS^ 
	CMD_POWER_DOWN_RESUME          = ((uint8_t)0xAB)              //Sequence : CS_ LB CS^ 
} POWER_DOWN_Tpye;

/*----------------------------------------The device will execute a internal operation--------------------------------------------*/
typedef enum
{
	CODE_CHIP_ERASE                 = 0,                          //Sequence : CS_ MB-UB-HB-LB CS^ 
	CODE_ENABLE_SECTOR_PROTECTION   = 1,                          //Sequence : CS_ MB-UB-HB-LB CS^ 
	CODE_DISABLE_SECTOR_PROTECTION  = 2,                          //Sequence : CS_ MB-UB-HB-LB CS^
	CODE_PROTECTION_REG_ERASE       = 3,                          //Sequence : CS_ MB-UB-HB-LB CS^
	CODE_POWER_OF_2                 = 4                           //Sequence : CS_ MB-UB-HB-LB CS^  		
} AT45_CMD_Type;

/*------------------------------------------------------------Read  data----------------------------------------------------------*/
typedef enum
{
	CMD_ARRAY_READ                 = ((uint8_t)0x03),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^ 
	CMD_BUF1_READ                  = ((uint8_t)0xD1),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used
	CMD_BUF2_READ                  = ((uint8_t)0xD3)              //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used
} AT45_CMD_READ_Type;

/*------------------------------------------------------------Read  data----------------------------------------------------------*/
typedef enum
{
	CMD_ARRAY_READ_FAST            = ((uint8_t)0x0B),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^
	CMD_BUF1_READ_FAST             = ((uint8_t)0xD4),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^  //Only Byte Address is used
	CMD_BUF2_READ_FAST             = ((uint8_t)0xD6)              //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-DUMMY1-R1....Rn CS^  //Only Byte Address is used
} AT45_CMD_READ_FAST_Type;

/*-----------------------------------------------------------Write  data----------------------------------------------------------*/
typedef enum
{
	CMD_BUF1_WRITE                 = ((uint8_t)0x84),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used    
	CMD_BUF2_WRITE                 = ((uint8_t)0x87),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^  //Only Byte Address is used 
	CMD_MAIN_PROG_THROUGH_BUF1     = ((uint8_t)0x82),             //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^
	CMD_MAIN_PROG_THROUGH_BUF2     = ((uint8_t)0x85)              //Sequence : CS_ CMD-ADDUB-ADDHB-ADDLB-R1....Rn CS^	
} AT45_CMD_WRITE_Type;

AT45DB_EXTE void  AT45_SPIInit(void);
AT45DB_EXTE uint8_t AT45_SendCMDWithAddr(AT45_CMD_WITH_ADDR_Type Type, uint32_t Address);                      // Send CMD
AT45DB_EXTE uint8_t AT45_SendCMD(AT45_CMD_Type Command);                                                       // Send CMD
AT45DB_EXTE uint8_t AT45_PowerDown(POWER_DOWN_Tpye NewState);                                                  // Send CMD power it down or resume
AT45DB_EXTE uint8_t AT45_Read(AT45_CMD_READ_Type ReadType, uint32_t Address, uint32_t Len, uint8_t *Des);          // Read data at low frequence
AT45DB_EXTE uint8_t AT45_ReadFast(AT45_CMD_READ_FAST_Type ReadType, uint32_t Address, uint32_t Len, uint8_t *Des); // Read data at high frequence
AT45DB_EXTE uint8_t AT45_Write(AT45_CMD_WRITE_Type WriteType, uint32_t Address, uint32_t Len, uint8_t *Src);       // Write

AT45DB_EXTE uint8_t AT45_MainMemWrite(uint32_t Address, uint32_t Len, uint8_t *Src); // Write data To Main memory For 512 mode
AT45DB_EXTE uint8_t AT45_MainMemRead(uint32_t Address, uint32_t Len, uint8_t *Des);  // Read data from Main memory
AT45DB_EXTE uint8_t AT45_ProtectionRegProg(uint8_t *Src);                            // Program Sector Protection Register Command
AT45DB_EXTE uint8_t AT45_ProtectionRegRead(uint8_t *Des);                            // Read Sector Protection Register Command
AT45DB_EXTE uint8_t AT45_LockDownRegProg(uint32_t Addr);                             // Sector Lockdown
AT45DB_EXTE uint8_t AT45_LockDownRegRead(uint8_t *Des);                              // Reading the Sector Lockdown Register
AT45DB_EXTE uint8_t AT45_SecurityRegProg(uint8_t *Src,uint8_t Len);                  // Programming the Security Register
AT45DB_EXTE uint8_t AT45_SecurityRegRead(uint8_t *Des,uint8_t Len);                  // Reading the Security Register
AT45DB_EXTE uint8_t AT45_StatusRead(void);                                           // Status Register Read
AT45DB_EXTE uint32_t AT45_DeviceIDRead(void);                                        // Manufacturer and Device ID Read


#undef AT45DB_EXTE

#endif
